package org.zfes.snowier.cloud.zbss.pmp.service.impl;

import java.util.Map;
import java.util.Optional;
import org.zfes.snowier.core.data.DataSet;
import org.zfes.snowier.core.exceptions.ServiceLogicalException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.zfes.snowier.core.util.ZBeanUtil;
import org.zfes.snowier.core.util.ZDateUtil;
import org.zfes.snowier.core.util.ZObjectUtil;
import org.zfes.snowier.core.util.ZAlert;
import org.zfes.snowier.core.util.ZAssert;
import org.zfes.snowier.common.dao.params.ParamMap;
import org.zfes.snowier.cloud.zbss.pmp.service.IPmpCloudMemberService;
import org.zfes.snowier.cloud.zbss.pmp.service.IPmpDocumentService;
import org.zfes.snowier.cloud.zbss.pmp.service.IPmpProjectService;
import org.zfes.snowier.cloud.zbss.pmp.service.IPmpProjectVersionService;
import org.zfes.snowier.cloud.zbss.pmp.dao.PmpDocumentMapper;
import org.zfes.snowier.cloud.zbss.pmp.dto.PmpDocumentCreateDto;
import org.zfes.snowier.cloud.zbss.pmp.dto.PmpDocumentUpdateDto;
import org.zfes.snowier.cloud.zbss.pmp.model.PmpCloudMember;
import org.zfes.snowier.cloud.zbss.pmp.model.PmpDocument;
import org.zfes.snowier.cloud.zbss.pmp.model.PmpProject;
import org.zfes.snowier.cloud.zbss.pmp.model.PmpProjectVersion;

import java.util.stream.Stream;

@Service
public class PmpDocumentServiceImpl implements IPmpDocumentService {
	@Autowired
	private PmpDocumentMapper pmpDocumentMapper;

	@Autowired
	private IPmpCloudMemberService pmpCloudMemberService;

	@Autowired
	private IPmpProjectService pmpProjectService;
	
	@Autowired
	private IPmpProjectVersionService pmpProjectVersionService;

	@Transactional(rollbackFor = Exception.class, readOnly = true)
	@Override
	public Optional<PmpDocument> loadPmpDocumentById(Long id) {
		if (id != null) {
			return Optional.ofNullable(pmpDocumentMapper.selectByPrimaryKey(id));
		}
		return Optional.empty();

	}

	@Transactional(rollbackFor = Exception.class)
	@Override
	public void deletePmpDocument(Long id) {
		ZAssert.notNull(id, "请选择要操作的数据");
		PmpDocument document = loadPmpDocumentById(id).orElseThrow(()->new ServiceLogicalException("未找到该文档"));
		document.setUpdatetime(ZDateUtil.newDate()).setStatus(Byte.valueOf("-1"));
		pmpDocumentMapper.update(document);
	}

	@Transactional(rollbackFor = Exception.class)
	@Override
	public void setPmpDocumentStatus(Long id, Byte status) {
		ZAssert.notNull(id, "请选择要操作的数据");
		ZAssert.notNull(status, "状态参数错误");

		if (!Stream.of(new Byte[] { -1, 0, 1 }).anyMatch(val -> val.equals(status))) {
			ZAlert.serviceLogicalError("状态参数错误");
		}
		pmpDocumentMapper.updateStatus(id, status);
	}

	@Transactional(rollbackFor = Exception.class, readOnly = true)
	@Override
	public DataSet loadPmpDocumentDataSet(Map<String, Object> params) {
		ParamMap pm = ParamMap.filterParam(params);
		DataSet ds = DataSet.newDS2(pmpDocumentMapper.selectListCount(pm), pmpDocumentMapper.selectMapListPage(pm));
		return ds;
	}

	@Transactional(rollbackFor = Exception.class)
	@Override
	public void createPmpDocument(Long createId, PmpDocumentCreateDto createDto) {
		ZAssert.notNull(createId, "创建者不能为空");
		ZBeanUtil.validateBean(createDto);

		PmpCloudMember member = pmpCloudMemberService.loadPmpCloudMemberById(createId)
				.orElseThrow(() -> new ServiceLogicalException("未找到该创建者"));
		ZAssert.equals(member.getStatus(), Byte.valueOf("1"), "该用户状态错误");

		PmpProject project = pmpProjectService.loadPmpProjectById(createDto.getProjectId())
				.orElseThrow(() -> new ServiceLogicalException("未查找到该项目"));
		ZAssert.notEquals(member.getStatus(), Byte.valueOf("-1"), "该项目已被删除");
		ZAssert.equals(createDto.getProjetVersionId(), project.getVersionId(), "该项目没有此版本号");

		PmpDocument document = new PmpDocument();
		ZBeanUtil.copy(createDto, document, true);
		document.setCreatetime(ZDateUtil.newDate());
		document.setUpdatetime(ZDateUtil.newDate());

		document.setCreatorUserId(createId).setCreatorUserName(member.getUserName())
				.setProjetVersion(project.getVersionName());
		pmpDocumentMapper.insertSelective(document);

	}

	@Transactional(rollbackFor = Exception.class)
	@Override
	public void updatePmpDocument(Long id, PmpDocumentUpdateDto updateDto) {
		ZAssert.notNull(id, "请选择要操作的数据");

		PmpDocument document = loadPmpDocumentById(id).orElseThrow(() -> new ServiceLogicalException("未查找到该文档"));
		ZAssert.notEquals(document.getStatus(), Byte.valueOf("-1"), "该文档已被删除");

		ZBeanUtil.copy(updateDto, document, true);
		if (ZObjectUtil.isNotNull(updateDto.getProjetVersionId())) {

			PmpProjectVersion projectVersion = pmpProjectVersionService.loadPmpProjectVersionById(updateDto.getProjetVersionId()).orElseThrow(()->new ServiceLogicalException("未查找到该项目版本号"));
			ZAssert.notEquals(projectVersion.getStatus(), Byte.valueOf("-1"),"该项目版本已被删除");
		    ZAssert.equals(document.getProjectId(), projectVersion.getProjectId(), "该项目不存在该版本号");
		    
		    document.setProjetVersion(projectVersion.getVersion());
		}
		if (ZObjectUtil.isNotNull(updateDto.getStatus())) {
			if (!Stream.of(new Byte[] { -1, 0, 1 }).anyMatch(val -> val.equals(updateDto.getStatus()))) {
				ZAlert.serviceLogicalError("状态参数错误");
			}
		}
		document.setUpdatetime(ZDateUtil.newDate());
		pmpDocumentMapper.update(document);
	}

}